package com.lyy.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import com.lyy.entity.Menu;
import com.lyy.exception.ServiceException;
import com.lyy.mapper.RoleMapper;
import com.lyy.util.JwtUtil;
import com.lyy.vo.LoginVO;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.lyy.entity.Admin;
import com.lyy.mapper.AdminMapper;
import com.lyy.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static com.lyy.entity.table.AdminTableDef.ADMIN;

/**
 * 后台用户表 服务层实现。
 *
 * @author LianYaoyun
 * @since 2024-06-22
 */
@Service
@CacheConfig(cacheNames = "admin")
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {

    @Autowired
    public AdminMapper adminMapper;

    @Autowired
    public RoleMapper roleMapper;
    @Override
    @CacheEvict(allEntries = true)
    public boolean remove(QueryWrapper query) {
        return super.remove(query);
    }

    @Override
    @CacheEvict(key = "#id")
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }

    @Override
    @CacheEvict(allEntries = true)
    public boolean removeByIds(Collection<? extends Serializable> ids) {
        return super.removeByIds(ids);
    }

    @Override
    @CacheEvict(allEntries = true)
    public boolean update(Admin entity, QueryWrapper query) {
        return super.update(entity, query);
    }

    @Override
    @CacheEvict(key = "#entity.id")
    public boolean updateById(Admin entity, boolean ignoreNulls) {
        return super.updateById(entity, ignoreNulls);
    }

    @Override
    @CacheEvict(allEntries = true)
    public boolean updateBatch(Collection<Admin> entities, int batchSize) {
        return super.updateBatch(entities, batchSize);
    }

    @Override
    @Cacheable(key = "#id", unless = "#result == null")
    public Admin getById(Serializable id) {
        // 查询Admin
        Admin admin = adminMapper.selectOneWithRelationsById(id);
        List<Menu> menus = new ArrayList<>();
        // 遍历全部 role 的 menu 并合并到一起
        admin.getRoles().forEach(role -> menus.addAll(role.getMenus()));
        // 将menus注入返回值
        admin.setMenus(menus);
        return admin;
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public Admin getOne(QueryWrapper query) {
        return super.getOne(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public <R> R getOneAs(QueryWrapper query, Class<R> asType) {
        return super.getOneAs(query, asType);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public Object getObj(QueryWrapper query) {
        return super.getObj(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public <R> R getObjAs(QueryWrapper query, Class<R> asType) {
        return super.getObjAs(query, asType);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public List<Object> objList(QueryWrapper query) {
        return super.objList(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public <R> List<R> objListAs(QueryWrapper query, Class<R> asType) {
        return super.objListAs(query, asType);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public List<Admin> list(QueryWrapper query) {
        return super.list(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public <R> List<R> listAs(QueryWrapper query, Class<R> asType) {
        return super.listAs(query, asType);
    }

    /**
     * @deprecated 无法通过注解进行缓存操作。
     */
    @Override
    @Deprecated
    public List<Admin> listByIds(Collection<? extends Serializable> ids) {
        return super.listByIds(ids);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public long count(QueryWrapper query) {
        return super.count(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #page.getPageSize() + ':' + #page.getPageNumber() + ':' + #query.toSQL()")
    public <R> Page<R> pageAs(Page<R> page, QueryWrapper query, Class<R> asType) {
        return super.pageAs(page, query, asType);
    }

    @Override
    public LoginVO login(String username, String password) {
        // 对密码进行MD5加密
        password = SecureUtil.md5(password);
        // 根据账号和密码查询管理员
        Admin admin = adminMapper.selectOneByQuery(QueryWrapper.create()
                .where(ADMIN.USERNAME.eq(username))
                .and(ADMIN.PASSWORD.eq(password)));

        if (ObjectUtil.isNull(admin)) {
            System.out.println(password);
            throw new ServiceException("账号或密码错误");

        }
        // 构建VO实体类
        LoginVO loginVO = new LoginVO();
        loginVO.setTokenHead("Bearer ");
        loginVO.setToken(JwtUtil.build(
                admin.getId(),
                admin.getNickName(),
                admin.getIcon()
        ));
        // 返回VO实体类
        return loginVO;
    }
}
